package com.androidme.app.framework.util;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.androidme.app.framework.base.AndroidMeResourceMessageException;

import java.util.List;

public class DialogUtil {
    private static final String PROGRESS_DIALOG_TITLE_RESOURCE = "progress_dialog_title";
    private static final String PROGRESS_DIALOG_MESSAGE_RESOURCE = "progress_dialog_message";

    private static volatile ProgressDialog progressDialog;
    private static volatile ProgressBar progressBar;

    /**
     * Show a Progress Bar
     *
     * @param context
     */
    public static void showProgressBar(Activity context) {
        synchronized (DialogUtil.class) {
            if (progressBar == null) {
                progressBar = new ProgressBar(context);
                FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                params.gravity = Gravity.CENTER;
                try{
                    context.addContentView(progressBar, params);
                }catch (Exception e){
                    e.printStackTrace();
                }
                progressBar.setVisibility(View.VISIBLE);
            }
            if (progressBar.getVisibility() == View.INVISIBLE) {
                progressBar.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * Hide Progress Bar
     */
    public static void hideProgressBar() {
        synchronized (DialogUtil.class) {
            if (progressBar != null) {
                progressBar.setVisibility(View.INVISIBLE);
                progressBar = null;
            }
        }
    }

    /**
     * Show a Progress Dialog
     *
     * @param context
     */
    public static void showProgressDialog(Context context) {
        showProgressDialog(context, "Loading...");
    }

    /**
     * Show a Progress Dialog
     *
     * @param context
     * @param title
     */
    public static void showProgressDialog(Context context, String title) {
        synchronized (DialogUtil.class) {
            showProgressDialog(context, title, "");
        }
    }

    /**
     * Show a Progress Dialog
     *
     * @param context
     * @param title
     * @param message
     */
    public static void showProgressDialog(Context context, String title, String message) {
        synchronized (DialogUtil.class) {
            if (progressDialog != null) {
                progressDialog.dismiss();
            }
            progressDialog = new ProgressDialog(context);
            progressDialog.setTitle(title);
            progressDialog.setMessage(message);
            progressDialog.show();
        }
    }

    /**
     * Hide a Progress Dialog
     */
    public static void hideProgressDialog() {
        synchronized (DialogUtil.class) {
            if (progressDialog != null) {
                progressDialog.hide();
            }
        }
    }


    /**
     * Creates a new ProgressDialog
     *
     * @param activity
     * @param progressDialogTitleId The resource id for the title. If this is less than or equal to 0, a default title
     *                              is used.
     * @param progressDialogMsgId   The resource id for the message.
     * @return The new dialog
     */
    public static ProgressDialog createProgressDialog(final Activity activity, int progressDialogTitleId, int progressDialogMsgId) {
        ProgressDialog progressDialog = new ProgressDialog(activity);
        if (progressDialogTitleId <= 0) {
            progressDialogTitleId = activity.getResources().getIdentifier(
                    PROGRESS_DIALOG_TITLE_RESOURCE, "string", activity.getPackageName());
        }
        progressDialog.setTitle(progressDialogTitleId);
        if (progressDialogMsgId <= 0) {
            progressDialogMsgId = activity.getResources().getIdentifier(
                    PROGRESS_DIALOG_MESSAGE_RESOURCE, "string", activity.getPackageName());
        }
        progressDialog.setMessage(activity.getString(progressDialogMsgId));
        progressDialog.setIndeterminate(true);
        progressDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                activity.onKeyDown(keyCode, event);
                return false;
            }
        });
//        progressDialog.setInverseBackgroundForced(true);
        return progressDialog;
    }

    /**
     * Creates a new Yes/No AlertDialog
     *
     * @param context
     * @param title
     * @param message
     * @param iconResourceId
     * @param listener
     * @return
     */
    public static AlertDialog newYesNoDialog(final Context context, String title,
                                             String message, int iconResourceId, DialogInterface.OnClickListener listener) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setCancelable(false);
        builder.setPositiveButton(android.R.string.yes, listener);
        builder.setNegativeButton(android.R.string.no, listener);

        builder.setTitle(title);
        builder.setMessage(message);
        builder.setIcon(iconResourceId);

        return builder.create();
    }

    /**
     * Creates a new AlertDialog to display a simple message
     *
     * @param context
     * @param title
     * @param message
     * @param iconResourceId
     * @return
     */
    public static AlertDialog newMessageDialog(final Context context, String title,
                                               String message, int iconResourceId) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setCancelable(false);
        builder.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        builder.setTitle(title);
        builder.setMessage(message);
        builder.setIcon(iconResourceId);

        return builder.create();
    }

    /**
     * Displays a error dialog with an exception as its body. Also displays a Send Email button to
     * send the exception to the developer. Implement the following resource IDs
     * error_report_email_address - The email address the exception is sent to.
     * error_report_email_subject - The subject of the email.
     * dialog_button_send_error_report - The text on the Send Email button.
     *
     * @param activity
     * @param title
     * @param error
     * @return
     */
    public static AlertDialog newErrorHandlerDialog(final Activity activity, String title, Exception error) {
        String screenMessage = "";
        if (error instanceof AndroidMeResourceMessageException) {
            screenMessage = activity.getString(((AndroidMeResourceMessageException) error).getClientMessageResourceId());
        } else {
            screenMessage = error.getLocalizedMessage();
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(title);
        builder.setMessage(screenMessage);
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        builder.setCancelable(false);
        builder.setPositiveButton(activity.getString(android.R.string.ok), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        if (IntentUtil.isIntentAvailable(activity, Intent.ACTION_SEND, IntentUtil.MIME_TYPE_EMAIL)) {
            int buttonId = activity.getResources().getIdentifier(
                    "dialog_button_send_error_report", "string", activity.getPackageName());
            String buttonText = activity.getString(buttonId);
            int bugEmailAddressId = activity.getResources().getIdentifier(
                    "error_report_email_address", "string", activity.getPackageName());
            String bugReportEmailAddress = activity.getString(bugEmailAddressId);
            int bugEmailSubjectId = activity.getResources().getIdentifier(
                    "error_report_email_subject", "string", activity.getPackageName());
            String bugReportEmailSubject = activity.getString(bugEmailSubjectId);
            final String diagnosis = DiagnosticUtil.createDiagnosis(activity, error);
            final Intent intent = IntentUtil.newEmailIntent(activity, bugReportEmailAddress, bugReportEmailSubject, diagnosis);
            builder.setNegativeButton(buttonText, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    activity.startActivity(intent);
                }
            });
        }

        return builder.create();
    }

    /**
     * Creates a AlertDialog that shows a list of elements. The listener's onClick method gets
     * called when the user taps a list item.
     *
     * @param <T>           The type of each element
     * @param context
     * @param title         the title or null to disable the title
     * @param elements      List of elements to be displayed. Each elements toString() method will be called.
     * @param listener      The listener to handle the onClick events.
     * @param closeOnSelect If true the dialog closes as soon as one list item is selected, otherwise multiple
     *                      onClick events may be sent.
     * @return The new dialog.
     */
    public static <T> Dialog newListDialog(final Activity context, String title,
                                           final List<T> elements, final DialogClickListener<T> listener,
                                           final boolean closeOnSelect) {
        return newListDialog(context, title, elements, listener, closeOnSelect, 0);
    }

    public static <T> Dialog newListDialog(final Activity context, String dialogTitle,
                                           final List<T> elements, final DialogClickListener<T> listener,
                                           final boolean closeOnSelect, int selectedItem) {
        final int entriesSize = elements.size();
        String[] entries = new String[entriesSize];
        for (int i = 0; i < entriesSize; i++) {
            entries[i] = elements.get(i).toString();
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        if (dialogTitle != null) {
            builder.setTitle(dialogTitle);
        }
        builder.setSingleChoiceItems(entries, selectedItem, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                if (closeOnSelect)
                    dialog.dismiss();
                listener.onClick(which, elements.get(which));
            }
        });

        return builder.create();
    }

    public interface DialogClickListener<T> {

        void onClick(int index, T element);

    }
}
